/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-18     BruceOu      first implementation
 */
//#include <stdint.h>
#include <rthw.h>
//#include <rtthread.h>
//#include <board.h>

#define LOG_TAG     "BSP.BOARD"    ///< 该模块对应的标签。不定义时，默认：NO_TAG
#define LOG_LVL     LOG_LVL_DBG   ///< 该模块对应的日志输出级别。不定义时，默认：调试级别
#include "string.h"
#include "board.h"


/**
  * @brief	死循环us延时
  * @param  nus 微妙数
  *
  * @retval void
  *
  * @author Taoking
  * @date
  * @note
  */
void delay_us(uint32_t nus)
{
//	OS_ERR err;
//	CPU_SR_ALLOC();
#define clock (SystemCoreClock / 1000000)

    uint32_t ticks;
    uint32_t told,tnow,tcnt = 0;
    uint32_t reload = SysTick->LOAD;	//LOAD的值
    ticks = clock * nus; 			//需要的节拍数
//    CPU_CRITICAL_ENTER();       /* close interrupt            */

    told = SysTick->VAL;        	//刚进入时的计数器值
    while(1)
    {
        tnow = SysTick->VAL;
        if(tnow != told)
        {
            if(tnow < told) tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了
            else tcnt += reload - tnow + told;
            told = tnow;
            if(tcnt >= ticks)break; //时间超过/等于要延迟的时间,则退出.
        }
    };

//    CPU_CRITICAL_EXIT();			//恢复关中断前状态

}


/** System Clock Configuration
*/
void SystemClock_Config(void)
{
    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
	  systick_clksource_set(SYSTICK_CLKSOURCE_HCLK);
    NVIC_SetPriority(SysTick_IRQn, 0);
}

/**
 * This is the timer interrupt service routine.
 *
 */
void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();
}

/**
 * This function will initial GD32 board.
 */
void rt_hw_board_init()
{
	  /* NVIC Configuration */
    nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0); 
	
    SystemClock_Config();

#ifdef BSP_USING_SDRAM
    rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END);
#else
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
	
	    /* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
#include "drv_gpio.h"
    rt_hw_pin_init();
#endif

    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
#include "drv_usart.h"
    gd32_hw_usart_init();
#endif
	
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

}



/**
 * This function will delay for some us.
 *
 * @param us the delay time of us
 */
void rt_hw_us_delay(rt_uint32_t us)
{
    rt_uint32_t start, now, delta, reload, us_tick;
    start = SysTick->VAL;
    reload = SysTick->LOAD;
    us_tick = SystemCoreClock / 1000000UL;
    do
    {
        now = SysTick->VAL;
        delta = start >= now ? start - now : reload + start - now;
    }
    while (delta < us_tick * us);
}

/*@}*/
